#include "../include/tokyo.h"

static void db_char_load_text_handler (GMarkupParseContext *context, const gchar *text, gsize text_len,
				gpointer user_data, GError **error);
static void db_char_load_error_handler (GMarkupParseContext *context, GError *error, gpointer user_data);

static const GMarkupParser db_char_parser = {
  NULL,
  NULL,
  db_char_load_text_handler,
  NULL,
  db_char_load_error_handler
};

#define DB_CHAR_LOAD_STRKEY_CONTROL(key, place)	\
{	\
	if (!g_ascii_strcasecmp (g_markup_parse_context_get_element (context), key))	\
	{	\
		place = g_strdup (text);	\
		return;	\
	}	\
}

static void db_char_load_text_handler (	GMarkupParseContext *context,
							const gchar *text,
							gsize text_len,
							gpointer user_data,
							GError **error)
{
	DB_CHAR_LOAD_STRKEY_CONTROL ("Name", ((S_CHAR*) user_data) ->name);

	g_set_error (error, TOKYO_ERROR,
						TOKYO_ERROR_DB_CHAR_LOAD_NO_MATCH,
						_("(chiave errata)-> %s"),
						g_markup_parse_context_get_element (context));
}

static void db_char_load_error_handler (	GMarkupParseContext *context,
							GError *error,
							gpointer user_data)
{
	tlog (P_ERROR, "db_char_load_error_handler", _("Errore in lettura %s"), error->message);
}

S_CHAR *db_char_load (const gchar *filename)
{
	gchar *contents;
	gsize  length;
	GError *error = NULL;
	GMarkupParseContext *context;
	S_CHAR* ch;

	if (!g_file_get_contents (filename, &contents, &length, &error))
	{
		tlog (P_ERROR, "db_char_load", _("Errore apertura (r) %s"), error->message);
		g_error_free (error);
		return NULL;
    }

	ch = g_new (S_CHAR, 1);
	char_init (ch);

	context = g_markup_parse_context_new (&db_char_parser, 0, ch, NULL);

	error = NULL;
	if (!g_markup_parse_context_parse (context, contents, length, &error))
	{
		g_markup_parse_context_free (context);
		g_error_free (error);
		char_free (ch);
		return NULL;
	}

	error = NULL;
	if (!g_markup_parse_context_end_parse (context, &error))
	{
		g_markup_parse_context_free (context);
		tlog (P_ERROR, "db_char_load", _("Errore lettura %s"), error->message);
		g_error_free (error);
		char_free (ch);
		g_free (ch);
		return NULL;
	}

	g_markup_parse_context_free (context);

	return ch;
}

#define DB_CHAR_CONTROL_STATE	\
{	\
	if (state == G_IO_STATUS_ERROR)	\
	{	\
		tlog (P_ERROR, "db_char_save", _("Errore scrittura %s-> %s"), filename, error->message);	\
		g_error_free (error);	\
		return FALSE;	\
	}	\
	if (state == G_IO_STATUS_EOF)	\
	{	\
		tlog (P_ERROR, "db_char_save", _("EOF in scrittura-> %s"), filename);	\
		g_error_free (error);	\
		return FALSE;	\
	}	\
	if (state == G_IO_STATUS_AGAIN)	\
	{	\
		tlog (P_ERROR, "db_char_save", _("Scrittura non eseguibile al momento-> %s"), filename);	\
		g_error_free (error);	\
		return FALSE;	\
	}	\
}

gboolean db_char_save (const gchar *filename, S_CHAR *ch)
{
	GIOChannel *ofile;
	GError *error = NULL;
	gsize size;
	GIOStatus state;

	if ((ofile = g_io_channel_new_file (filename, "w", &error)) == NULL)
	{
		tlog (P_ERROR, "db_char_save", _("Errore apertura (w)-> %s"), error->message);
		g_error_free (error);
		return FALSE;
	}

	error = NULL;
	state = g_io_channel_write_chars (ofile,
				g_markup_printf_escaped ("<Name>%s</Name>", ch->name),
				-1, &size, &error);

	DB_CHAR_CONTROL_STATE;


	g_io_channel_close (ofile);

	return TRUE;
}
